<?php
/**
 * Loader    	系统核心
 * @copyright   Copyright(c) 2024-2034
 * @author      tianjie <527707665@qq.com>
 * @link        http://www.tinphp.com/
 * @version     4.1
 */

namespace tian;

class Loader
{
	protected static $appPath = '';
	protected static $vendorPath = '';
	
	//路径映射 根命名空间目录
	public static $vendorMap = [];
	
	public function __construct(string $appPath = '',string $vendorPath = '')
    {
        self::$appPath = $appPath;
        self::$vendorPath = $vendorPath;
        self::$vendorMap['app'] = $appPath;
    }

    /**
     * 注册自动加载机制
     * @access public
     * @param callable|null $autoload 自动加载处理方法
     * @return void
     */
    public static function register(callable $autoload = null)
    {
        // 注册系统自动加载
        spl_autoload_register($autoload ?: 'tian\\Loader::autoload', true, true);
		
        //自动加载composer类库
        if (file_exists(self::$vendorPath . "autoload.php")) {
            require_once(self::$vendorPath . "autoload.php");
        }
    }

    /**
     * 自动加载器
     */
    public static function autoload($class = null): void
    {
        $file = self::findFile($class);
        if (file_exists($file)) {
            self::includeFile($file);
        }
    }

    /**
     * 解析文件路径
     */
    private static function findFile($class): string
    {
        //顶级命名空间
        $vendor = substr($class, 0, strpos($class, '\\'));
        if(isset(self::$vendorMap[$vendor])){
            // 文件基目录
            $vendorDir = self::$vendorMap[$vendor];
            // 文件相对路径
            $filePath = substr($class, strlen($vendor) + 1) . '.php';
            // 文件标准路径
            return strtr($vendorDir . $filePath, '\\', DIRECTORY_SEPARATOR);
        }else{
            return '';
        }
    }

    /**
     * 引入文件
     */
    private static function includeFile($file): void
    {
        if (is_file($file)) {
            include $file;
        }
    }

    /**
     * 字符串命名风格转换
     * type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格
     * @access public
     * @param  string  $name    字符串
     * @param  integer $type    转换类型
     * @param  bool    $ucfirst 首字母是否大写（驼峰规则）
     * @return string
     */
    public static function parseName($name, $type = 0, $ucfirst = true)
    {
        if ($type) {
            $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
                return strtoupper($match[1]);
            }, $name);

            return $ucfirst ? ucfirst($name) : lcfirst($name);
        }

        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
    }

}